package myJs.admin

import myJs.tool.Tool.{layerOptions, myElement}
import myJs.Utils._

import myJs.myPkg.bootstrap.Bootstrap.default._
import myJs.myPkg.jquery._
import myJs.myPkg.ztree.Ztree
import myJs.myPkg.{LayerOptions, Swal, SwalOptions}
import org.scalajs.dom.ext.Ajax
import org.scalajs.dom.{Element, Event, FormData, document}
import scalatags.Text.all._

import scala.scalajs.js
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.scalajs.js.JSON
import argonaut._
import Argonaut._
import myJs.Implicits._
import myJs.tool.Tool
import org.scalajs.dom.ext.Ajax.InputData
import scala.scalajs.js.Dynamic.{global => g}

/**
 * Created by yz on 2019/4/25
 */
@JSExportTopLevel("GzPathSet")
object GzPathSet {
  val url = g.jsRoutes.controllers.AdminController.getChildrenNodes().url.toString

  val setting = js.Dictionary(
    "view" -> js.Dictionary(
      "expandSpeed" -> ""
    ),
    "async" -> js.Dictionary(
      "enable" -> true,
      "url" -> url,
      "autoParam" -> js.Array("id"),
    ),
    "data" -> js.Dictionary(
      "simpleData" -> js.Dictionary(
        "enable" -> true
      )
    ),
    "callback" -> js.Dictionary(
      "onClick" -> onClick,
      "beforeExpand" -> beforeExpand,
    ),
  )

  @JSExport("init")
  def init = {
    getGzPath.foreach { data =>
      val json = JSON.parse(data).toJDS
      $(":input[name='gzPath']").`val`(json("gzPath"))
    }

    bootStrapValidator
    initWidth

  }

  def getTreeNodes = {
    val url = g.jsRoutes.controllers.AdminController.getTreeNodes().url.toString
    Ajax.get(url = s"${url}").map { xhr =>
      xhr.responseText
    }
  }

  def getGzPath = {
    val url = g.jsRoutes.controllers.AdminController.getGzPath().url.toString
    Ajax.get(url = s"${url}").map { xhr =>
      xhr.responseText
    }
  }

  def onClick: js.Function = (e: Event, treeId: String, treeNode: js.Any) => {
    val zTree = Ztree.getZTreeObj(treeId)
    val nodes = zTree.getSelectedNodes()
    val v = nodes.map(_ ("id")).mkString(",")
    $("#citySel").`val`(v)
    refreshFileTree(v)
    g.$("#form").bootstrapValidator("revalidateField", "gzPath")
  }

  def refreshFileTree(dir: String) = {
    val setting = js.Dictionary(
      "view" -> js.Dictionary(
        "expandSpeed" -> ""
      ),
      "data" -> js.Dictionary(
        "simpleData" -> js.Dictionary(
          "enable" -> true
        )
      ),
      "callback" -> js.Dictionary(
        "beforeExpand" -> beforeExpand,
      ),
    )
    val url = g.jsRoutes.controllers.AdminController.getFiles().url.toString
    Ajax.get(url = s"${url}?gzPath=${dir}", headers = Map("Content-Type" -> "application/json")).map { xhr =>
      val data = xhr.responseText.toJArJDS
      val treeId = "fileTree"
      Ztree.init($(s"#${treeId}"), setting, data)
    }
  }

  def beforeExpand: js.Function = (treeId: String, treeNode: js.Dictionary[String]) => {
    ajaxGetNodes(treeNode, "refresh")
    true
  }

  def ajaxGetNodes(treeNode: js.Dictionary[String], reloadType: String) = {
    val zTree = Ztree.getZTreeObj("treeDemo")
    if (reloadType == "refresh") {
      zTree.updateNode(treeNode)
    }
    zTree.reAsyncChildNodes(treeNode, reloadType, true)
  }

  def selectNode = {
    val treeObj = Ztree.getZTreeObj("treeDemo")
    val nodes = treeObj.transformToArray(treeObj.getNodes())
    val gzPath = $(":input[name='gzPath']").`val`()
    val nodeOp = nodes.filter(_ ("id") == gzPath).headOption
    nodeOp match {
      case Some(node) =>
        treeObj.selectNode(node)
      case None =>
        treeObj.cancelSelectedNode()
    }
  }

  def initWidth = {
    val cityObj = $("#citySel").parent()
    val width = cityObj.css("width").toString.replaceAll("px$", "").toDouble
    $(s"#menuContent").css("width", s"${width}px")
  }

  @JSExport("updateGzPath")
  def updateGzPath = {
    val formId = "form"
    val bv = jQuery(s"#${formId}").data("bootstrapValidator")
    bv.validate()
    val valid = bv.isValid().toB
    if (valid) {
      val formData = new FormData(document.getElementById("form").toHTMLFormElement)
      val url = g.jsRoutes.controllers.AdminController.updateGzPath().url.toString
      Ajax.post(url = s"${url}", data = formData,
        responseType = "application/json").map { xhr =>
        val json = xhr.responseText.toJDS
        if (json("operate") == "update") {
          layer.msg("源目录更新成功！", LayerOptions.icon(1).time(1000))
        }
      }
    }
  }

  @JSExport("hideMenu")
  def hideMenu: JQuery = {
    $("#menuContent").fadeOut("fast")
    $("body").unbind("mousedown", onBodyDown)
  }

  @JSExport("showMenu")
  def showMenu = {
    val cityObj = $("#citySel")
    val cityOffset = $("#citySel").offset()
    val parentLeft = $("#parentPanel").offset().left
    val left = cityOffset.left - parentLeft + 15
    val top = cityOffset.top + cityObj.outerHeight() - 135
    $("#menuContent").css("left", s"${left}px").css("top", s"${top}px").
      slideDown("fast")
    $("#treeDemo").css("width", cityObj.css("width"))
    $("body").bind("mousedown", onBodyDown)
    getTreeNodes.foreach { data =>
      val jsons = JSON.parse(data).toJArJDS
      Ztree.init($("#treeDemo"), setting, jsons)
      selectNode
    }

  }

  @JSExport("onBodyDown")
  def onBodyDown = (y: Element, e: Event) => {
    val targetElem = e.target.toElement
    val b = targetElem.id == "menuBtn" || targetElem.id == "menuContent" ||
      $(targetElem).parents("#menuContent").length > 0
    if (!b) {
      hideMenu
    }
  }

  def bootStrapValidator = {
    val url = g.jsRoutes.controllers.AdminController.gzPathCheck().url.toString
    val dict = js.Dictionary(
      "feedbackIcons" -> js.Dictionary(
        "valid" -> "glyphicon glyphicon-ok",
        "invalid" -> "glyphicon glyphicon-remove",
        "validating" -> "glyphicon glyphicon-refresh",
      ),
      "fields" -> js.Dictionary(
        "gzPath" -> js.Dictionary(
          "validators" -> js.Dictionary(
            "notEmpty" -> js.Dictionary(
              "message" -> "源目录不能为空！"
            ),
            "remote" -> js.Dictionary(
              "message" -> "源目录不存在！",
              "url" -> url,
              "delay" -> 500,
              "type" -> "POST",
            ),
          )
        ),


      )
    )
    g.$("#form").bootstrapValidator(dict)
  }

}
